package com.cneport.das.server.util.wmq;

import com.cneport.das.common.utils.DateUtil;
import com.cneport.das.common.utils.StringUtil;
import com.ibm.mq.constants.MQConstants;
import com.ibm.mq.headers.MQDataException;
import com.ibm.mq.headers.pcf.PCFException;
import com.ibm.mq.headers.pcf.PCFMessage;
import com.ibm.mq.headers.pcf.PCFMessageAgent;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

/**
 * IBM 官方PCF创建队列的方式
 *
 * @author GavinZhang
 */
@Component
public class QueueOperator {


    /**
     * 创建队列
     *
     * @param agent         通过沟通队列管理器参数的方式脸上队列管理器
     * @param qName         队列名
     * @param corpName      公司名
     * @param transmitQueue 是否是传输MQ
     * @throws MQDataException
     * @throws IOException
     */
    public void createQueue(MQConnAgent agent, String qName, String corpName, boolean transmitQueue)
            throws MQDataException, IOException {
        PCFMessage pcfCmd = prepareCreate(qName, corpName, transmitQueue);
        try {
            agent.getAgent().send(pcfCmd);
        } catch (PCFException pcfe) {
            if (pcfe.reasonCode == MQConstants.MQRCCF_OBJECT_ALREADY_EXISTS) {
                System.out.println("The queue \"" + qName
                        + "\" already exists on the queue manager.");
            } else {
                throw pcfe;
            }
        }
        return;
    }

    /**
     * 列出对应队列管理器上的所有队列
     *
     * @param mQAgent
     * @return
     * @throws MQDataException
     * @throws IOException
     */
    public Set<String> listQueueNames(MQConnAgent mQAgent) throws MQDataException, IOException {
        return queryAllQueues(mQAgent.getAgent());

    }

    private PCFMessage prepareCreate(String qName, String corpName, boolean transmitQueue) {
        int queueType = MQConstants.MQQT_LOCAL;

        final int DEPTH = 100000;
        // Create the PCF message type for the create queue.
        // NB: The parameters must be added in a specific order or an exception (3015)
        // will be thrown.
        PCFMessage pcfCmd = new PCFMessage(MQConstants.MQCMD_CREATE_Q);

        // Queue name - Mandatory.
        pcfCmd.addParameter(MQConstants.MQCA_Q_NAME, qName);

        // Queue Type - Optional.
        pcfCmd.addParameter(MQConstants.MQIA_Q_TYPE, queueType);
        //持久化队列
        pcfCmd.addParameter(MQConstants.MQIA_DEF_PERSISTENCE, 1);
        pcfCmd.addParameter(MQConstants.MQIA_MAX_Q_DEPTH, DEPTH);
        if (transmitQueue) {
            // Queue Type - This must be the second parameter!
            pcfCmd.addParameter(MQConstants.MQIA_USAGE, MQConstants.MQUS_TRANSMISSION);
        }

        // Add description.
        String desc = "Java API 动态创建的队列！" + DateUtil.now();
        if (!StringUtil.isEmpty(corpName)) {
            desc = corpName;
        }
        pcfCmd.addParameter(MQConstants.MQCA_Q_DESC, desc);
        return pcfCmd;
    }


    private Set<String> queryAllQueues(PCFMessageAgent agent) throws MQDataException,
            IOException {
        // Create the PCF message type for the inquire.
        PCFMessage pcfCmd = new PCFMessage(MQConstants.MQCMD_INQUIRE_Q_NAMES);

        // Add the inquire rules.
        pcfCmd.addParameter(MQConstants.MQCA_Q_NAME, "*");

        // Queue type = ALL.
        pcfCmd.addParameter(MQConstants.MQIA_Q_TYPE, MQConstants.MQQT_ALL);

        // Execute the command. The returned object is an array of PCF messages.
        PCFMessage[] pcfResponse = agent.send(pcfCmd);

        Set<String> set = new HashSet<>();

        // required information.
       /* System.out.println("+-----+------------------------------------------------+");
        System.out.println("|Index|                    Queue Name                  |");
        System.out.println("+-----+------------------------------------------------+");*/

        String[] names = (String[]) pcfResponse[0].getParameterValue(MQConstants.MQCACF_Q_NAMES);

        for (int index = 0; index < names.length; index++) {
          /*  System.out.println("|" + (index + mQAgent.getPadding()).substring(0, 5) + "|"
                    + (names[index] + mQAgent.getPadding()).substring(0, 48) + "|");*/
            //包含系统级别的Queue
            String qName = names[index];
            if (!qName.startsWith("AMQ.") && !qName.startsWith("SYSTEM.")) {
                set.add(qName.trim());
            }
        }
        //System.out.println("+-----+------------------------------------------------+");
        return set;

    }

}
